import { defineStore } from "pinia";
import { Menu } from "@/types/menu";
import { reactive } from "vue";

const MENUID = 'menuid';
const MENU = 'menuList';
const CURRENTMENU = 'currentMenu'

export const useMenuStore = defineStore('menu', {
  state: () => ({
    menuid: localStorage.getItem(MENUID) || '1',
    menuList: reactive<Array<Menu>>(JSON.parse(localStorage.getItem(MENU) || '[]')),
    currentMenu: JSON.parse(localStorage.getItem(CURRENTMENU) || JSON.stringify({ menuid: "9999", menu: "home", name: "home", url: "/", isMenu: true, menuList: [] })),
    menuLevel: reactive<Array<Menu>>([])
  }),
  getters: {
    length: (state) => state.menuList.length
  },
  actions: {
    /**
     * 添加菜单，尾部插入
     * @param menu 菜单
     */
    addMenu(menu: Menu): String | void {
      menu.isFree = true
      let menuid = this.menuid
      menu.menuid = menuid
      this.menuid = String(Number(menuid) + 1)
      // 尾部插入菜单
      if (!!menu.fatherMenuid) {
        let fatherMenu = this.findMenu(this.menuList, menu.fatherMenuid)
        if (!fatherMenu) {
          this.menuid = menuid
          return '菜单【' + menu.fatherMenuid + '】不存在'
        }
        fatherMenu.isMenu = false
        fatherMenu.menuList.push(menu)
      } else {
        this.menuList.push(menu)
      }
      localStorage.setItem(MENUID, this.menuid)
      localStorage.setItem(MENU, JSON.stringify(this.menuList))
      this.levelMenu()
    },

    /**
     * 移除菜单
     * @param menuid 菜单id 
     * @returns void
     */
    removeMenu(menuid: String): String | void {
      let flag = false
      this.menuList.map(menu => {
        flag = reMenu(menu, menuid) || flag
      })
      if (!flag) {
        return '菜单【' + menuid + '】不存在'
      }
      localStorage.setItem(MENU, JSON.stringify(this.menuList))
      this.levelMenu()
    },

    /**
     * 恢复菜单
     * @param menuid 菜单id
     * @returns void
     */
    recoverMenu(menuid: String): String | void {
      let menu = this.findMenu(this.menuList, menuid)
      if (!menu) {
        return '菜单【' + menuid + '】不存在'
      }
      menu.isFree = true
      localStorage.setItem(MENU, JSON.stringify(this.menuList))
      this.levelMenu()
    },

    /**
     * 保存当前打开的菜单
     * @param menu 当前菜单
     */
    saveCurrentMenu(menu: Menu): void {
      localStorage.setItem(CURRENTMENU, JSON.stringify(menu))
    },

    /**
     * 删除当前打开的菜单
     * 跳到home
     */
    deleteCurrentMenu(): void {
      localStorage.removeItem(CURRENTMENU)
    },

    /**
     * 查找菜单
     * @param menuList 菜单列表 
     * @param menuid 菜单id
     * @returns Menu || null: null说明未找到
     */
    findMenu(menuList: Array<Menu>, menuid: String): Menu | null {
      let target: Menu | null = null
      if (!menuList) return target
      menuList.map(menu => {
        if (menu.menuid === menuid) {
          target = menu
          return
        }
        if (!target)
          target = this.findMenu(menu.menuList, menuid)
      })
      return target
    },

    /**
     * 所有菜单--转换成单层菜单
     * @returns Array<Menu>
     */
    levelMenu(): Array<Menu> {
      this.menuLevel = reactive<Array<Menu>>([])
      this.levelMenuAuxi(this.menuList)
      return this.menuLevel
    },
    levelMenuAuxi(menuList: Array<Menu>) {
      menuList.map(menu => {
        // if (!menu.isFree) return
        this.menuLevel.push(menu)
        if (!menu.isMenu) this.levelMenuAuxi(menu.menuList)
      })
    },


    /**
     * 删除菜单
     * @param menuid 菜单id
     */
    deleteMenu(menuid: String | undefined): String | void {
      if (!menuid) return
      let flag = false
      this.menuList.map(menu => {
        flag = deMenu(this.menuList, menu, menuid) || flag
      })
      if (!flag) {
        return '菜单【' + menuid + '】不存在'
      }
      localStorage.setItem(MENU, JSON.stringify(this.menuList))
      this.levelMenu()
    },

    /**
     * 修改菜单
     * @param menu 修改后的菜单
     */
    updateMenu(menu: Menu): String | void {
      let flag = false
      this.menuList.map(m => {
        flag = upMenu(this.menuList, m, menu) || flag
      })
      if (!flag) {
        return '菜单【' + menu.menuid + '】不存在'
      }
      localStorage.setItem(MENU, JSON.stringify(this.menuList))
      this.levelMenu()
    }
  }
})

/**
 * 逐层查找并移除菜单
 * @param menu 菜单
 * @param menuid 菜单id
 * @returns boolean true:成功 false:未找到菜单
 */
const reMenu = (menu: Menu, menuid: String): boolean => {
  if (menu.menuid === menuid) {
    menu.isFree = false
    return true
  }
  if (menu.isMenu) return false
  let menuList = menu.menuList;
  let flag = false
  for (let i = 0; i < menuList.length; i++) {
    flag = reMenu(menuList[i], menuid)
    if (flag) return flag
  }
  return flag
}

/**
 * 逐层查找并删除菜单
 * @param menuList 父级菜单list
 * @param menu 菜单
 * @param menuid 菜单id
 * @returns boolean true:成功 false:未找到菜单
 */
const deMenu = (menuList: Array<Menu>, menu: Menu, menuid: String): boolean => {
  if (menu.menuid === menuid) {
    menuList.splice(menuList.indexOf(menu), 1)
    return true
  }
  if (menu.isMenu) return false
  let menuLi = menu.menuList
  let flag = false
  for (let i = 0; i < menuLi.length; i++) {
    flag = deMenu(menuLi, menuLi[i], menuid)
    if (flag) return flag
  }
  return flag
}

/**
 * 逐层查找并修改菜单
 * @param menuList 父级菜单list
 * @param menu 菜单
 * @param menuid 菜单id
 * @returns boolean true:成功 false:未找到菜单
 */
const upMenu = (menuList: Array<Menu>, menu: Menu, newMenu: Menu): boolean => {
  if (menu.menuid === newMenu.menuid) {
    menuList.splice(menuList.indexOf(menu), 1, newMenu)
    return true
  }
  if (menu.isMenu) return false
  let menuLi = menu.menuList
  let flag = false
  for (let i = 0; i < menuLi.length; i++) {
    flag = upMenu(menuLi, menuLi[i], newMenu)
    if (flag) return flag
  }
  return flag
}
